# coding: utf-8

from __future__ import absolute_import, division, print_function, unicode_literals

import os

from apitest.engine.const.constant import *
from apitest.engine.const.enums import Env, IDC
from apitest.engine.const.model import EnvModel
from apitest.engine.logging import logger

DEFAULT_IDC = {
    Env.Online: IDC.PROD,
    Env.Pre: IDC.PROD,
    Env.BOE: IDC.BOE,
    Env.Dev: IDC.BOE,
}

REGION_IDC_MAP = {
    Env.Online: [IDC.PROD, IDC.LF, IDC.HL, IDC.LQ, IDC.SINF, IDC.SINFONLINE, IDC.SINFONLINEA, IDC.SINFONLINEC],
    Env.Pre: [IDC.PROD, IDC.LF, IDC.HL, IDC.LQ, IDC.SINF, IDC.SINFONLINE, IDC.SINFONLINEA, IDC.SINFONLINEC],
    Env.BOE: [IDC.BOE, IDC.SINFBOE],
    Env.Dev: [IDC.BOE, IDC.SINFBOE],
}

REGION_ENV_TAG_KEYWORDS_MAP = {
    Env.Online: ["prod", "ppe_", "canary"],
    Env.Pre: ["prod", "ppe_", "canary"],
    Env.BOE: ["prod", "boe_"],
    Env.Dev: ["prod", "boe_"]
}


class CurrentEnv:

    @staticmethod
    def is_dev():
        region = os.getenv(REGION_KEY)
        if region == Env.Dev.value:
            return True
        return False

    @staticmethod
    def is_boe():
        region = os.getenv(REGION_KEY)
        if region not in [Env.Online.value, Env.Pre.value]:
            return True
        return False

    @staticmethod
    def is_ppe():
        region = os.getenv(REGION_KEY)
        env_tag = os.getenv(ENV_LABEL_KEY)
        if region in [Env.Online.value, Env.Pre.value] and env_tag.startswith('ppe_'):
            return True
        return False

    def is_online(self):
        region = os.getenv(REGION_KEY)
        if region in [Env.Online.value, Env.Pre.value] and not self.is_ppe():
            return True
        return False

    def is_canary(self):
        env_tag = os.getenv(ENV_LABEL_KEY)
        if self.is_online() and env_tag == 'canary':
            return True
        return False


class BaseEnv(CurrentEnv):

    @property
    def region(self):
        name = os.environ.get(REGION_KEY)
        try:
            return Env(name)
        except ValueError:
            if name:
                raise Exception("region is error, region need in %s" % [e.value for e in Env])

    @property
    def idc(self):
        name = os.environ.get(IDC_KEY)
        try:
            return IDC(name)
        except ValueError:
            if name:
                raise Exception("idc is error, idc need in %s" % [idc.value for idc in IDC])

    @property
    def env_tag(self) -> str:
        env_tag = os.getenv(ENV_LABEL_KEY)
        return env_tag

    @staticmethod
    def set_env(env_info: EnvModel):

        region, idc, env_tag = env_info.region, env_info.idc, env_info.env_tag
        if region:
            os.environ[REGION_KEY] = region.value
        else:
            try:
                os.environ.pop(REGION_KEY)
            except KeyError:
                logger.info("%s is not set" % REGION_KEY)
        if idc:
            os.environ[IDC_KEY] = idc.value
        else:
            try:
                os.environ.pop(IDC_KEY)
            except KeyError:
                logger.info("%s is not set" % IDC_KEY)
        if env_tag:
            os.environ[ENV_LABEL_KEY] = env_tag
        else:
            try:
                os.environ.pop(ENV_LABEL_KEY)
            except KeyError:
                logger.info("%s is not set" % ENV_LABEL_KEY)

    @staticmethod
    def check_region_tag_mach(region: Env, env_tag: str):
        for e in REGION_ENV_TAG_KEYWORDS_MAP[region]:
            if env_tag.startswith(e):
                return True
        logger.warning("region：%s and env_tag: %s not match." % (region, env_tag))
        return False

    def _env_parser(self, region, idc, env_tag):
        # region处理
        if region is None:
            region = Env.BOE

        # env tag处理
        if env_tag:
            if not self.check_region_tag_mach(region, env_tag):
                env_tag = "prod"
        else:
            env_tag = "prod"

        # idc处理
        if idc is not None and idc not in REGION_IDC_MAP[region]:
            idc = DEFAULT_IDC[region]
            if idc is not None:
                idc = IDC(idc)

        # 重新写入环境变量
        env_info = EnvModel(region=region)
        env_info.idc = idc
        env_info.env_tag = env_tag
        return env_info

    def init_env(self):
        env_info = self._env_parser(self.region, self.idc, self.env_tag)
        self.set_env(env_info)


run_env = BaseEnv()
run_env.init_env()
logger.info("runtime env: region is %s, env_tag is %s", run_env.region, run_env.env_tag)
